<!-- 文章编辑页面 - 提供文章的创建、编辑功能，支持Markdown语法和实时预览 -->
<template>
  <div class="post-edit">
    <!-- 示例数据提示 -->
    <el-alert
      v-if="isUsingSampleData"
      title="示例数据模式"
      description="后端API调用失败，当前显示的是示例数据。所有操作将不会真正保存到服务器。"
      type="warning"
      :closable="false"
      show-icon
      class="sample-data-notice"
    />
    
    <!-- 页面头部 - 包含标题和操作按钮 -->
    <div class="page-header">
      <div class="header-left">
        <h1 class="page-title">{{ isEdit ? '编辑文章' : '新建文章' }}</h1>
        <p class="page-subtitle">完善文章信息，支持 Markdown 语法编辑</p>
      </div>
      <div class="header-actions">
        <!-- 保存草稿按钮 -->
        <el-button @click="saveAsDraft" :loading="saving" plain>
          <el-icon>
            <Document />
          </el-icon>
          保存草稿
        </el-button>
        <!-- 发布文章按钮 -->
        <el-button type="primary" @click="publishPost" :loading="publishing">
          <el-icon>
            <Promotion />
          </el-icon>
          {{ isEdit ? '更新发布' : '发布文章' }}
        </el-button>
      </div>
    </div>

    <!-- 主要内容区域 - 左右分栏布局 -->
    <div class="edit-content" v-loading="isLoading">
      <!-- 左侧编辑区域 -->
      <div class="edit-main">
        <!-- 文章标题输入区域 -->
        <div class="form-section">
          <label class="section-label">文章标题</label>
          <el-input v-model="postForm.title" placeholder="请输入文章标题..." size="large" class="title-input" maxlength="100"
            show-word-limit />
        </div>

        <!-- 文章摘要输入区域 -->
        <div class="form-section">
          <label class="section-label">文章摘要</label>
          <el-input v-model="postForm.summary" type="textarea" placeholder="请输入文章摘要..." :rows="3" maxlength="200"
            show-word-limit />
        </div>

        <!-- Markdown 编辑器区域 -->
        <div class="form-section">
          <label class="section-label">文章内容</label>
          <MarkdownEditor v-model="postForm.content" placeholder="请输入文章内容，支持 Markdown 语法..." height="500px"
            @change="handleContentChange" @file-upload="handleFileUpload" />
        </div>
      </div>

      <!-- 右侧设置面板 -->
      <div class="edit-sidebar">
        <!-- 发布设置区域 -->
        <div class="sidebar-section">
          <h3 class="section-title">发布设置</h3>

          <!-- 文章状态选择 -->
          <div class="form-item">
            <label class="form-label">文章状态</label>
            <el-select v-model="postForm.status" placeholder="选择状态">
              <el-option label="草稿" value="draft" />
              <el-option label="已发布" value="published" />
              <el-option label="已归档" value="archived" />
            </el-select>
          </div>

          <!-- 发布时间选择 -->
          <div class="form-item">
            <label class="form-label">发布时间</label>
            <el-date-picker v-model="postForm.publishTime" type="datetime" placeholder="选择发布时间"
              format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
          </div>
        </div>

        <!-- 分类和标签设置区域 -->
        <div class="sidebar-section">
          <h3 class="section-title">分类和标签</h3>

          <!-- 文章分类选择 -->
          <div class="form-item">
            <label class="form-label">文章分类</label>
            <el-select v-model="postForm.categoryId" placeholder="选择分类">
              <el-option v-for="category in categories" :key="category.id" :label="category.name"
                :value="category.id" />
            </el-select>
          </div>

          <!-- 文章标签选择 -->
          <div class="form-item">
            <label class="form-label">文章标签</label>
            <el-select v-model="postForm.tags" multiple filterable allow-create placeholder="选择或创建标签">
              <el-option v-for="tag in tags" :key="tag.id" :label="tag.name" :value="tag.name" />
            </el-select>
          </div>
        </div>

        <!-- 封面图片上传区域 -->
        <div class="sidebar-section">
          <h3 class="section-title">封面图片</h3>

          <div class="cover-upload">
            <el-upload class="cover-uploader" :show-file-list="false" :before-upload="beforeCoverUpload"
              :http-request="handleCoverUpload" accept="image/*">
              <img v-if="postForm.coverImage" :src="postForm.coverImage" class="cover-image" />
              <el-icon v-else class="cover-uploader-icon">
                <Plus />
              </el-icon>
            </el-upload>
            <p class="upload-tip">建议尺寸：1200x600px，支持 JPG、PNG 格式</p>
          </div>
        </div>

        <!-- SEO 设置区域 -->
        <div class="sidebar-section">
          <h3 class="section-title">SEO 设置</h3>

          <!-- SEO标题 -->
          <div class="form-item">
            <label class="form-label">SEO 标题</label>
            <el-input v-model="postForm.seoTitle" placeholder="SEO 标题（可选）" maxlength="60" show-word-limit />
          </div>

          <!-- SEO描述 -->
          <div class="form-item">
            <label class="form-label">SEO 描述</label>
            <el-input v-model="postForm.seoDescription" type="textarea" placeholder="SEO 描述（可选）" :rows="3"
              maxlength="160" show-word-limit />
          </div>

          <!-- SEO关键词 -->
          <div class="form-item">
            <label class="form-label">SEO 关键词</label>
            <el-input v-model="postForm.seoKeywords" placeholder="SEO 关键词，用逗号分隔" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
// 导入Vue 3 Composition API核心功能
import { ref, reactive, computed, onMounted } from 'vue'
// 导入Vue Router用于页面导航和路由参数获取
import { useRoute, useRouter } from 'vue-router'
// 导入Element Plus组件和消息提示
import { ElMessage, ElMessageBox } from 'element-plus'
// 导入Element Plus图标组件
import {
  Document,
  Promotion,
  Edit,
  List,
  Link,
  Picture,
  Plus,
  Loading
} from '@element-plus/icons-vue'

// 导入升级版Markdown编辑器组件
import MarkdownEditor from '../../components/MarkdownEditor.vue'
// 导入DOMPurify用于HTML内容净化
import DOMPurify from 'dompurify'
// 导入API工具函数
import { get, post, put, API_PATHS } from '@/utils/api'

// 路由相关
const route = useRoute()
const router = useRouter()

// 响应式数据定义
const isEdit = computed(() => route.params.id !== undefined) // 是否为编辑模式
const saving = ref(false) // 保存草稿加载状态
const publishing = ref(false) // 发布文章加载状态
const showPreview = ref(false) // 是否显示预览模式
const isUsingSampleData = ref(false) // 是否使用示例数据
const isLoading = ref(false) // 数据加载状态

// 类型定义
interface Article {
  id?: number
  title: string
  summary: string
  content: string
  status: 'draft' | 'published' | 'archived'
  publishTime?: string
  categoryId?: number
  tags: string[]
  coverImage?: string
  seoTitle?: string
  seoDescription?: string
  seoKeywords?: string
  createdAt?: string
  updatedAt?: string
}

interface Category {
  id: number
  name: string
  description?: string
  parentId?: number
  sort: number
}

interface Tag {
  id: number
  name: string
  color?: string
  count?: number
}

interface ArticleRequest {
  title: string
  summary: string
  content: string
  status: 'draft' | 'published' | 'archived'
  publishTime?: string
  categoryId?: number
  tags: string[]
  coverImage?: string
  seoTitle?: string
  seoDescription?: string
  seoKeywords?: string
}

interface ArticleResponse {
  success: boolean
  data: Article
  message?: string
}

interface CategoriesResponse {
  success: boolean
  data: Category[]
  message?: string
}

interface TagsResponse {
  success: boolean
  data: Tag[]
  message?: string
}

// 文章表单数据对象
const postForm = reactive<ArticleRequest>({
  title: '', // 文章标题
  summary: '', // 文章摘要
  content: '', // 文章内容
  status: 'draft', // 文章状态
  publishTime: '', // 发布时间
  categoryId: undefined, // 分类ID
  tags: [], // 标签数组
  coverImage: '', // 封面图片URL
  seoTitle: '', // SEO标题
  seoDescription: '', // SEO描述
  seoKeywords: '' // SEO关键词
})

// 分类数据
const categories = ref<Category[]>([])
// 标签数据
const tags = ref<Tag[]>([])

// 示例数据
const sampleCategories: Category[] = [
  { id: 1, name: '技术', description: '技术相关文章', sort: 1 },
  { id: 2, name: '生活', description: '生活感悟', sort: 2 },
  { id: 3, name: '感想', description: '个人感想', sort: 3 },
  { id: 4, name: '教程', description: '技术教程', sort: 4 }
]

const sampleTags: Tag[] = [
  { id: 1, name: 'Vue.js', color: '#42b883', count: 15 },
  { id: 2, name: 'React', color: '#61dafb', count: 12 },
  { id: 3, name: 'JavaScript', color: '#f7df1e', count: 25 },
  { id: 4, name: 'CSS', color: '#1572b6', count: 18 },
  { id: 5, name: 'HTML', color: '#e34f26', count: 10 },
  { id: 6, name: '前端', color: '#ff6b6b', count: 30 },
  { id: 7, name: '后端', color: '#4ecdc4', count: 20 },
  { id: 8, name: '数据库', color: '#45b7d1', count: 8 }
]

const sampleArticle: Article = {
  id: 1,
  title: '示例文章标题',
  summary: '这是一篇示例文章的摘要，展示了文章编辑页面的功能特性...',
  content: `# 示例文章

这是一篇示例文章的内容，支持 **Markdown** 语法。

## 功能特性

- 支持 Markdown 编辑
- 实时预览
- 分类标签管理
- SEO 优化
- 封面图片上传

## 代码示例

\`\`\`javascript
// 这是一个JavaScript代码示例
function hello() {
  console.log('Hello, World!');
}
\`\`\`

## 总结

这是一个完整的文章编辑示例，展示了所有功能的使用方法。`,
  status: 'draft',
  categoryId: 1,
  tags: ['Vue.js', '前端'],
  coverImage: '',
  seoTitle: '示例文章标题 - SEO优化',
  seoDescription: '这是一篇关于文章编辑功能的示例文章',
  seoKeywords: 'Vue.js,前端,Markdown,编辑器'
}

// 使用示例数据的函数
const useSampleData = () => {
  isUsingSampleData.value = true
  categories.value = sampleCategories
  tags.value = sampleTags
  
  if (isEdit.value) {
    Object.assign(postForm, sampleArticle)
  }
  
  ElMessage.warning('后端API调用失败，已加载示例数据')
}

// API调用函数
/**
 * 获取文章详情
 * @param id 文章ID
 */
const fetchArticleDetail = async (id: string) => {
  try {
    const response = await get<ArticleResponse>(API_PATHS.ADMIN_ARTICLE.DETAIL(id), {
      timeout: 8000,
      retry: 2
    })
    
    if (response && response.success && response.data) {
      Object.assign(postForm, response.data)
      ElMessage.success('文章数据加载成功')
    } else {
      throw new Error(response?.message || '获取文章数据失败')
    }
  } catch (error: any) {
    console.error('获取文章详情失败:', error)
    ElMessage.error(`获取文章详情失败: ${error.message}`)
    useSampleData()
  }
}

/**
 * 获取分类列表
 */
const fetchCategories = async () => {
  try {
    const response = await get<CategoriesResponse>(API_PATHS.ADMIN_ARTICLE.CATEGORIES, {
      timeout: 8000,
      retry: 2
    })
    
    if (response && response.success && response.data) {
      categories.value = response.data as unknown as Category[]
    } else {
      throw new Error(response?.message || '获取分类列表失败')
    }
  } catch (error: any) {
    console.error('获取分类列表失败:', error)
    ElMessage.error(`获取分类列表失败: ${error.message}`)
    useSampleData()
  }
}

/**
 * 获取标签列表
 */
const fetchTags = async () => {
  try {
    const response = await get<TagsResponse>(API_PATHS.ADMIN_ARTICLE.TAGS, {
      timeout: 8000,
      retry: 2
    })
    
    if (response && response.success && response.data) {
      tags.value = response.data as unknown as Tag[]
    } else {
      throw new Error(response?.message || '获取标签列表失败')
    }
  } catch (error: any) {
    console.error('获取标签列表失败:', error)
    ElMessage.error(`获取标签列表失败: ${error.message}`)
    useSampleData()
  }
}

/**
 * 保存草稿API调用
 */
const saveDraftAPI = async () => {
  try {
    const articleData: ArticleRequest = {
      title: postForm.title,
      summary: postForm.summary,
      content: postForm.content,
      status: 'draft',
      categoryId: postForm.categoryId || undefined,
      tags: postForm.tags,
      coverImage: postForm.coverImage,
      seoTitle: postForm.seoTitle,
      seoDescription: postForm.seoDescription,
      seoKeywords: postForm.seoKeywords
    }
    
    const response = await post<ArticleResponse>(API_PATHS.ADMIN_ARTICLE.SAVE_DRAFT, articleData, {
      timeout: 10000,
      retry: 2
    })
    
    if (response && response.success) {
      ElMessage.success('草稿保存成功')
      return true
    } else {
      throw new Error(response?.message || '保存草稿失败')
    }
  } catch (error: any) {
    console.error('保存草稿失败:', error)
    ElMessage.error(`保存草稿失败: ${error.message}`)
    return false
  }
}

/**
 * 创建文章API调用
 */
const createArticleAPI = async () => {
  try {
    const articleData: ArticleRequest = {
      title: postForm.title,
      summary: postForm.summary,
      content: postForm.content,
      status: postForm.status,
      publishTime: postForm.publishTime,
      categoryId: postForm.categoryId || undefined,
      tags: postForm.tags,
      coverImage: postForm.coverImage,
      seoTitle: postForm.seoTitle,
      seoDescription: postForm.seoDescription,
      seoKeywords: postForm.seoKeywords
    }
    
    const response = await post<ArticleResponse>(API_PATHS.ADMIN_ARTICLE.CREATE, articleData, {
      timeout: 10000,
      retry: 2
    })
    
    if (response && response.success) {
      ElMessage.success('文章创建成功')
      return true
    } else {
      throw new Error(response?.message || '创建文章失败')
    }
  } catch (error: any) {
    console.error('创建文章失败:', error)
    ElMessage.error(`创建文章失败: ${error.message}`)
    return false
  }
}

/**
 * 更新文章API调用
 */
const updateArticleAPI = async (id: string) => {
  try {
    const articleData: ArticleRequest = {
      title: postForm.title,
      summary: postForm.summary,
      content: postForm.content,
      status: postForm.status,
      publishTime: postForm.publishTime,
      categoryId: postForm.categoryId || undefined,
      tags: postForm.tags,
      coverImage: postForm.coverImage,
      seoTitle: postForm.seoTitle,
      seoDescription: postForm.seoDescription,
      seoKeywords: postForm.seoKeywords
    }
    
    const response = await put<ArticleResponse>(API_PATHS.ADMIN_ARTICLE.UPDATE(id), articleData, {
      timeout: 10000,
      retry: 2
    })
    
    if (response && response.success) {
      ElMessage.success('文章更新成功')
      return true
    } else {
      throw new Error(response?.message || '更新文章失败')
    }
  } catch (error: any) {
    console.error('更新文章失败:', error)
    ElMessage.error(`更新文章失败: ${error.message}`)
    return false
  }
}

// 计算属性 - 渲染Markdown内容为HTML
const renderedContent = computed(() => {
  if (!postForm.content) return ''
  // 简单的 Markdown 渲染（临时方案）
  let html = postForm.content
    .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') // 粗体
    .replace(/\*(.*?)\*/g, '<em>$1</em>') // 斜体
    .replace(/### (.*?)$/gm, '<h3>$1</h3>') // 三级标题
    .replace(/## (.*?)$/gm, '<h2>$1</h2>') // 二级标题
    .replace(/# (.*?)$/gm, '<h1>$1</h1>') // 一级标题
    .replace(/^- (.*?)$/gm, '<li>$1</li>') // 列表项
    .replace(/\n/g, '<br>') // 换行
  return DOMPurify.sanitize(html) // 净化HTML内容防止XSS攻击
})

/**
 * 插入Markdown语法到编辑器
 * 在选中的文本前后插入指定的Markdown标记
 * @param before - 插入到选中文本前的标记
 * @param after - 插入到选中文本后的标记
 */
const insertMarkdown = (before: string, after: string) => {
  const textarea = document.querySelector('.content-textarea textarea') as HTMLTextAreaElement
  if (!textarea) return

  const start = textarea.selectionStart
  const end = textarea.selectionEnd
  const selectedText = postForm.content.substring(start, end)

  // 构建新的文本内容
  const newText = postForm.content.substring(0, start) +
    before + selectedText + after +
    postForm.content.substring(end)

  postForm.content = newText

  // 设置光标位置到选中文本的中间
  setTimeout(() => {
    textarea.focus()
    textarea.setSelectionRange(start + before.length, start + before.length + selectedText.length)
  }, 0)
}

/**
 * 保存文章为草稿
 * 将当前文章内容保存为草稿状态
 */
const saveAsDraft = async () => {
  saving.value = true
  try {
    const success = await saveDraftAPI()
    if (success) {
      ElMessage.success('草稿保存成功')
    }
  } catch (error) {
    ElMessage.error('保存失败，请重试')
  } finally {
    saving.value = false
  }
}

/**
 * 发布文章
 * 验证必填字段并发布文章
 */
const publishPost = async () => {
  // 验证文章标题
  if (!postForm.title.trim()) {
    ElMessage.warning('请输入文章标题')
    return
  }

  // 验证文章内容
  if (!postForm.content.trim()) {
    ElMessage.warning('请输入文章内容')
    return
  }

  publishing.value = true
  try {
    let success = false
    
    if (isEdit.value) {
      // 编辑模式：更新文章
      success = await updateArticleAPI(route.params.id as string)
    } else {
      // 新建模式：创建文章
      success = await createArticleAPI()
    }
    
    if (success) {
      ElMessage.success(isEdit.value ? '文章更新成功' : '文章发布成功')
      router.push('/admin/posts')
    }
  } catch (error) {
    ElMessage.error('发布失败，请重试')
  } finally {
    publishing.value = false
  }
}

/**
 * 封面图片上传前的验证
 * 检查文件类型和大小
 * @param file - 上传的文件对象
 * @returns 是否允许上传
 */
const beforeCoverUpload = (file: File) => {
  const isImage = file.type.startsWith('image/')
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return false
  }
  if (!isLt10M) {
    ElMessage.error('图片大小不能超过 10MB!')
    return false
  }
  return true
}

/**
 * 封面图片上传成功回调
 * @param response - 服务器响应数据
 */
const handleCoverSuccess = (response: any) => {
  postForm.coverImage = response.url
  ElMessage.success('封面图片上传成功')
}

/**
 * 封面图片上传失败回调
 */
const handleCoverError = () => {
  ElMessage.error('封面图片上传失败')
}

/**
 * 封面图片上传处理
 * @description 处理封面图片上传，先尝试后端API，失败时使用本地Blob URL
 * @param options - 上传选项
 */
const handleCoverUpload = async (options: any) => {
  const file = options.file
  const isImage = file.type.startsWith('image/')
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    options.onError()
    return
  }
  if (!isLt10M) {
    ElMessage.error('图片大小不能超过 10MB!')
    options.onError()
    return
  }

  // 显示上传进度
  ElMessage.info('封面图片上传中...')

  try {
    // 首先尝试后端API上传
    const formData = new FormData()
    formData.append('image', file)
    
    const response = await fetch('/api/upload/image', {
      method: 'POST',
      body: formData
    })
    
    if (response.ok) {
      const result = await response.json()
      if (result.success && result.url) {
        // 后端上传成功，使用服务器返回的URL
        postForm.coverImage = result.url
        ElMessage.success('封面图片上传成功')
        options.onSuccess(result)
        return
      } else {
        throw new Error(result.message || '服务器返回错误')
      }
    } else {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`)
    }
  } catch (error: any) {
    // 后端API上传失败，回退到本地Blob URL
    console.warn('后端API上传失败，使用本地Blob URL:', error.message)
    
    ElMessage.warning('服务器上传失败，已保存到本地预览')
    
    // 创建本地Blob URL
    const localUrl = URL.createObjectURL(file)
    postForm.coverImage = localUrl
    
    // 模拟成功回调，传递本地URL
    options.onSuccess({ 
      url: localUrl, 
      local: true, // 标记为本地URL
      message: '图片已保存到本地预览，刷新页面后将丢失'
    })
    
    // 显示详细信息
    ElMessage({
      message: '图片已保存到本地预览，刷新页面后将丢失',
      type: 'warning',
      duration: 5000
    })
  }
}

/**
 * 内容变化处理
 * @description 处理Markdown编辑器内容变化事件
 */
const handleContentChange = (value: string) => {
  postForm.content = value
}

/**
 * 文件上传处理
 * @description 处理MD文件上传，自动设置文章标题
 * @param file - 上传的文件对象
 * @param title - 从文件名提取的标题
 */
const handleFileUpload = (file: File, title: string) => {
  // 如果文章标题为空，则使用文件名作为标题
  if (!postForm.title.trim()) {
    postForm.title = title
    ElMessage.info(`已自动设置文章标题为："${title}"`)
  } else {
    ElMessage.info(`文件"${title}"已上传，文章标题保持不变`)
  }
}

// 页面加载时获取数据
onMounted(async () => {
  isLoading.value = true
  
  try {
    // 获取分类和标签数据
    await Promise.all([
      fetchCategories(),
      fetchTags()
    ])
    
    // 如果是编辑模式，获取文章详情
    if (isEdit.value) {
      await fetchArticleDetail(route.params.id as string)
    }
  } catch (error) {
    console.error('页面数据加载失败:', error)
    useSampleData()
  } finally {
    isLoading.value = false
  }
})
</script>

<style scoped lang="scss">
// 导入文章编辑页面样式
@use '../../assets/styles/admin/_post-edit';
</style>